commonlibsse_ng\re\b\BSTArray/
scrap.rs

1use core::{
2    ffi::c_void,
3    marker::PhantomData,
4    ops::{Index, IndexMut, Range, RangeBounds},
5    ptr::{self, NonNull},
6    slice,
7};
8
9use crate::re::BSTArray::allocator::Allocator;
10
11use super::allocator::BSScrapArrayAllocator;
12
13#[repr(C)]
14#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct BSTArrayBase {
16    pub size: u32,
17}
18const_assert_eq!(core::mem::size_of::<BSTArrayBase>(), 0x4);
19
20impl BSTArrayBase {
21    /// Create a empty array size.
22    #[inline]
23    pub const fn new() -> Self {
24        Self { size: 0 }
25    }
26}
27
28///  `BSScrapArray<T, A>` is a growable array type that provides a dynamic array
29///
30/// Internally, the array stores:
31/// - a pointer to the data buffer
32/// - the number of elements (`len`)
33/// - the capacity of the allocation (`cap`)
34///
35/// # Features
36///
37/// - Compatible with Havok's binary layout for `BSTArray<T>`
38/// - Supports growable or fixed-capacity semantics
39/// - Custom allocator support (`A: Allocator`)
40/// - Methods similar to `Vec<T>`
41///
42/// # Panics
43///
44/// Most methods panic under the following conditions:
45///
46/// - Indexing out of bounds (`array[index]`)
47/// - Reserving more capacity than is possible
48/// - Pushing to a full fixed-capacity array (if applicable)
49///
50/// # Example
51///
52/// ```no_run
53/// use commonlibsse_ng::re::BSTArray::BSScrapArray;
54///
55/// let mut array = BSScrapArray::<i32>::new();
56/// array.push(1);
57/// array.push(2);
58/// assert_eq!(array.len(), 2);
59/// assert_eq!(array[1], 2);
60/// ```
61///
62/// # See also
63///
64/// - [`Vec<T>`]
65/// - [`Box<[T]>`]
66#[repr(C)]
67pub struct BSScrapArray<T, A = BSScrapArrayAllocator>
68where
69    A: Allocator,
70{
71    __base: A,
72    __base1: BSTArrayBase,
73    _marker: PhantomData<T>,
74}
75const _: () = assert!(core::mem::size_of::<BSScrapArray<u8>>() == 0x20);
76
77impl<T, A> BSScrapArray<T, A>
78where
79    A: Allocator,
80{
81    /// Creates a new, empty `BSTArray<T, A>` with the specified allocator.
82    ///
83    /// The array will not allocate until elements are pushed.
84    ///
85    /// # Example
86    /// ```no_run
87    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
88    ///
89    /// let array = BSScrapArray::<i32>::new();
90    /// assert!(array.is_empty());
91    /// ```
92    pub fn new() -> Self {
93        Self { __base: A::new(), __base1: BSTArrayBase::new(), _marker: PhantomData }
94    }
95
96    /// Creates a new, empty `BSTArray<T, A>` with the capacity.
97    ///
98    /// # Example
99    /// ```no_run
100    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
101    ///
102    /// let array = BSScrapArray::<i32>::with_capacity(5);
103    /// assert_eq!(array.capacity(), 5);
104    /// ```
105    pub fn with_capacity(capacity: usize) -> Self {
106        let mut allocator = A::new();
107
108        let new_data = unsafe { allocator.allocate(A::ptr_layout(capacity)) };
109        let capacity = capacity as u32;
110        Self::set_allocator_traits(&mut allocator, new_data, capacity);
111
112        Self { __base: allocator, __base1: BSTArrayBase::new(), _marker: PhantomData }
113    }
114
115    /// Returns the number of elements in the array.
116    ///
117    /// This is also referred to as the array’s "length".
118    ///
119    /// # Example
120    /// ```no_run
121    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
122    ///
123    /// let array = BSScrapArray::<i32>::new();
124    /// assert_eq!(array.len(), 0);
125    /// ```
126    #[inline]
127    pub const fn len(&self) -> usize {
128        self.__base1.size as usize
129    }
130
131    /// Returns `true` if the array contains no elements.
132    ///
133    /// # Example
134    /// ```no_run
135    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
136    ///
137    /// let array = BSScrapArray::<i32>::new();
138    /// assert!(array.is_empty());
139    /// ```
140    #[inline]
141    pub const fn is_empty(&self) -> bool {
142        self.len() == 0
143    }
144
145    /// Returns the total number of elements the array can hold without reallocating.
146    ///
147    /// This is the allocated capacity, which may be larger than the current length.
148    ///
149    /// # Example
150    /// ```no_run
151    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
152    ///
153    /// let mut array = BSScrapArray::<i32>::with_capacity(10);
154    /// assert!(array.capacity() >= 10);
155    /// ```
156    #[inline]
157    pub fn capacity(&self) -> usize {
158        self.__base.capacity() as usize
159    }
160
161    /// Shrinks the capacity of the array as much as possible.
162    ///
163    /// It will drop any excess capacity not used by the current elements.
164    ///
165    /// # Examples
166    ///
167    /// ```no_run
168    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
169    ///
170    /// let mut array = BSScrapArray::<i32>::with_capacity(10);
171    /// array.push(1);
172    /// assert_eq!(array.len(), 1);
173    /// array.shrink_to_fit();
174    /// assert!(array.capacity() >= array.len());
175    /// ```
176    #[inline]
177    pub fn shrink_to_fit(&mut self) {
178        let len = self.len();
179        self.change_capacity(len);
180    }
181
182    /// Appends an element to the back of the array.
183    ///
184    /// # Panics
185    /// Panics if the array is at fixed capacity and cannot grow.
186    ///
187    /// # Example
188    /// ```no_run
189    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
190    ///
191    /// let mut array = BSScrapArray::<i32>::new();
192    /// array.push(5);
193    /// assert_eq!(array[0], 5);
194    /// ```
195    #[inline]
196    pub fn push(&mut self, value: T) {
197        let size = self.__base1.size;
198        if size == self.__base.capacity() {
199            self.grow();
200        }
201        unsafe {
202            self.as_mut_ptr().add(size as usize).write(value);
203        }
204
205        self.__base1.size += 1;
206    }
207
208    /// Removes the last element from the array and returns it, or `None` if it's empty.
209    ///
210    /// # Example
211    /// ```no_run
212    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
213    ///
214    /// let mut array = BSScrapArray::<i32>::new();
215    /// array.push(1);
216    /// assert_eq!(array.pop(), Some(1));
217    /// assert_eq!(array.pop(), None);
218    /// ```
219    #[inline]
220    pub fn pop(&mut self) -> Option<T> {
221        let len = self.len();
222        if len == 0 {
223            None
224        } else {
225            self.__base1.size -= 1;
226            unsafe { Some(ptr::read(self.as_ptr().add(len - 1))) }
227        }
228    }
229
230    /// Returns a reference to the element at the given index, if it exists.
231    ///
232    /// # Example
233    /// ```no_run
234    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
235    ///
236    /// let mut array = BSScrapArray::<i32>::new();
237    /// array.push(42);
238    /// assert_eq!(array.get(0), Some(&42));
239    /// assert_eq!(array.get(1), None);
240    /// ```
241    #[inline]
242    pub fn get(&self, index: usize) -> Option<&T> {
243        if index < self.len() {
244            return unsafe { self.as_ptr().add(index).as_ref() };
245        }
246        None
247    }
248
249    /// Returns a mutable reference to the element at the given index, if it exists.
250    ///
251    /// # Example
252    /// ```no_run
253    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
254    ///
255    /// let mut array = BSScrapArray::<i32>::new();
256    /// array.push(10);
257    /// if let Some(x) = array.get_mut(0) {
258    ///     *x += 1;
259    /// }
260    /// assert_eq!(array[0], 11);
261    /// ```
262    #[inline]
263    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
264        if index < self.len() {
265            return unsafe { self.as_mut_ptr().add(index).as_mut() };
266        }
267        None
268    }
269
270    /// Clears the array, removing all elements but preserving the capacity.
271    ///
272    /// # Examples
273    /// ```no_run
274    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
275    ///
276    /// let mut array = BSScrapArray::<i32>::with_capacity(10);
277    /// array.push(1);
278    /// array.push(2);
279    /// assert_eq!(array.len(), 2);
280    /// array.clear();
281    /// assert_eq!(array.len(), 0);
282    /// assert_eq!(array.capacity(), 10); // Capacity is preserved
283    /// ```
284    #[inline]
285    pub fn clear(&mut self) {
286        // Drop all elements in the array without changing capacity
287        for i in 0..self.len() {
288            unsafe {
289                // SAFETY: we're dropping each element in place
290                ptr::drop_in_place(self.as_mut_ptr().add(i));
291            }
292        }
293
294        self.__base1.size = 0; // Reset the length, but keep the allocated capacity
295    }
296
297    /// Returns a raw pointer to the array’s buffer.
298    ///
299    /// This is useful for FFI or direct memory manipulation.
300    #[inline]
301    pub fn as_ptr(&self) -> *const T {
302        self.__base.as_ptr().cast()
303    }
304
305    /// Returns a mutable raw pointer to the array’s buffer.
306    #[inline]
307    pub fn as_mut_ptr(&mut self) -> *mut T {
308        self.__base.as_mut_ptr().cast()
309    }
310
311    /// Checks if the array contains the given element.
312    ///
313    /// Returns `true` if the element is present in the array, and `false` otherwise.
314    ///
315    /// # Examples
316    ///
317    /// ```no_run
318    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
319    ///
320    /// let mut array = BSScrapArray::<i32>::with_capacity(10);
321    /// array.push(1);
322    /// array.push(2);
323    /// assert!(array.contains(&1));
324    /// assert!(!array.contains(&3));
325    /// ```
326    #[inline]
327    pub fn contains(&self, value: &T) -> bool
328    where
329        T: PartialEq,
330    {
331        for i in 0..self.len() {
332            if let Some(item) = self.get(i) {
333                if item == value {
334                    return true;
335                }
336            }
337        }
338        false
339    }
340
341    /// Retains only the elements that satisfy the predicate.
342    ///
343    /// This method takes a closure that accepts an element of the array and returns a boolean.
344    /// Elements for which the closure returns `true` will be kept, while elements for which
345    /// it returns `false` will be removed.
346    ///
347    /// # Examples
348    ///
349    /// ```no_run
350    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
351    ///
352    /// let mut array = BSScrapArray::<i32>::with_capacity(10);
353    /// array.push(1);
354    /// array.push(2);
355    /// array.push(3);
356    /// array.retain(|&x| x > 1);
357    /// assert_eq!(array.len(), 2);
358    /// assert!(array.contains(&2));
359    /// assert!(array.contains(&3));
360    /// ```
361    #[inline]
362    pub fn retain<F>(&mut self, mut f: F)
363    where
364        F: FnMut(&T) -> bool,
365    {
366        let mut retained = 0;
367
368        for i in 0..self.len() {
369            let elem = match unsafe { self.as_ptr().add(i).as_ref() } {
370                Some(elem) => elem,
371                None => continue,
372            };
373
374            if f(elem) {
375                if retained != i {
376                    unsafe {
377                        let src = self.as_ptr().add(i);
378                        let dst = self.as_mut_ptr().add(retained);
379                        ptr::copy_nonoverlapping(src, dst, 1);
380                    }
381                }
382                retained += 1;
383            } else {
384                // Drop elements that do not match the predicate
385                unsafe { ptr::drop_in_place(self.as_mut_ptr().add(i)) };
386            }
387        }
388
389        self.__base1.size = retained as u32;
390    }
391
392    /// Resizes the array to the specified length.
393    ///
394    /// If the array is resized to a larger length, the new elements will be initialized
395    /// using the default constructor for `T`. If the array is resized to a smaller length,
396    /// elements at the end will be dropped.
397    ///
398    /// # Examples
399    ///
400    /// ```no_run
401    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
402    ///
403    /// let mut array = BSScrapArray::<i32>::with_capacity(10);
404    /// array.push(1);
405    /// array.push(2);
406    /// array.resize(5, 0);
407    /// assert_eq!(array.len(), 5);
408    /// assert_eq!(array[3], 0);
409    /// ```
410    #[inline]
411    pub fn resize(&mut self, new_size: usize, value: T)
412    where
413        T: Clone,
414    {
415        let prev_size = self.len();
416        if new_size > prev_size {
417            for _ in prev_size..new_size {
418                self.push(value.clone());
419            }
420        } else {
421            for i in new_size..prev_size {
422                unsafe { ptr::drop_in_place(self.as_mut_ptr().add(i)) };
423            }
424        }
425        self.__base1.size = new_size as u32;
426    }
427
428    /// Removes a range of elements from the array, returning them as a vector.
429    ///
430    /// This method removes the elements within the specified range and returns them as
431    /// a `Vec<T>`. The range must be within the bounds of the array.
432    ///
433    /// # Examples
434    ///
435    /// ```no_run
436    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
437    ///
438    /// let mut array = BSScrapArray::<i32>::with_capacity(10);
439    /// array.push(1);
440    /// array.push(2);
441    /// array.push(3);
442    /// array.push(4);
443    /// array.push(5);
444    /// let drained = array.drain(0..2);
445    /// assert_eq!(drained.collect::<Vec<_>>(), vec![1, 2]);
446    /// assert_eq!(array.len(), 3);
447    /// assert_eq!(array[0], 3);
448    /// assert_eq!(array[1], 4);
449    /// assert_eq!(array[2], 5);
450    /// ```
451    ///
452    /// # Panics
453    /// Panics if the range is out of bounds.
454    #[inline]
455    pub fn drain<R>(&mut self, range: R) -> BSTDrain<'_, T, A>
456    where
457        R: RangeBounds<usize>,
458    {
459        let len = self.len();
460        let Range { start, end } = stdx::slice::range(range, ..len);
461        debug_assert!(start <= end);
462        debug_assert!(end <= len);
463
464        // Need this.
465        // If the size is not changed before creating iter for Drain, inconsistencies will occur.
466        self.__base1.size = start as u32;
467
468        BSTDrain {
469            iter: unsafe { core::slice::from_raw_parts(self.as_ptr().add(start), end - start) }
470                .iter(),
471            tail_start: end,
472            tail_len: len - end,
473            array: unsafe { NonNull::new_unchecked(self as *mut Self) },
474        }
475    }
476
477    /// Returns a slice of all elements in the array.
478    #[inline]
479    pub fn as_slice(&self) -> &[T] {
480        let ptr = self.as_ptr();
481        let len = self.len();
482
483        if ptr.is_null() || (len == 0) {
484            return &[];
485        }
486        unsafe { slice::from_raw_parts(ptr, len) }
487    }
488
489    /// Returns a mutable slice of all elements in the array.
490    #[inline]
491    pub fn as_mut_slice(&mut self) -> &mut [T] {
492        let ptr = self.as_mut_ptr();
493        let len = self.len();
494
495        if ptr.is_null() || (len == 0) {
496            return &mut [];
497        }
498        unsafe { slice::from_raw_parts_mut(ptr, len) }
499    }
500
501    /// Returns an iterator over the elements of the array.
502    ///
503    /// This iterator yields references to the elements in the array.
504    ///
505    /// # Examples
506    ///
507    /// ```no_run
508    /// use commonlibsse_ng::re::BSTArray::BSScrapArray;
509    ///
510    /// let mut array = BSScrapArray::<i32>::with_capacity(10);
511    /// array.push(1);
512    /// array.push(2);
513    /// let sum: i32 = array.iter().sum();
514    /// assert_eq!(sum, 3);
515    /// ```
516    #[inline]
517    pub const fn iter(&self) -> BSTArrayIterator<'_, T, A> {
518        BSTArrayIterator { array: self, index: 0 }
519    }
520
521    fn grow(&mut self) {
522        const MIN_CAPACITY: usize = 4;
523        const GROWTH_FACTOR: usize = 2;
524
525        let old_capacity = self.capacity();
526        let new_capacity =
527            if old_capacity == 0 { MIN_CAPACITY } else { old_capacity * GROWTH_FACTOR };
528        self.change_capacity(new_capacity);
529    }
530
531    fn change_capacity(&mut self, new_capacity: usize) {
532        let new_data = if new_capacity > 0 {
533            let layout = A::ptr_layout(new_capacity);
534            unsafe { self.__base.allocate(layout).cast::<T>() }
535        } else {
536            ptr::null_mut()
537        };
538
539        let old_data = self.__base.as_mut_ptr().cast::<T>();
540        if !old_data.is_null() {
541            let old_capacity = self.capacity();
542            if !new_data.is_null() {
543                let copy_count = core::cmp::min(old_capacity, new_capacity);
544                // Safety: There is no uninitialized location because allocate is 0 filled.
545                unsafe { ptr::copy_nonoverlapping(old_data, new_data, copy_count) };
546            }
547
548            unsafe { self.__base.deallocate(old_data.cast()) };
549        }
550
551        Self::set_allocator_traits(&mut self.__base, new_data.cast(), new_capacity as u32);
552    }
553
554    fn set_allocator_traits(allocator: &mut A, data: *mut c_void, capacity: u32) {
555        allocator.set_allocator_traits(data, capacity, core::mem::size_of::<T>());
556    }
557}
558
559impl<T, A> Index<usize> for BSScrapArray<T, A>
560where
561    A: Allocator,
562{
563    type Output = T;
564
565    #[inline]
566    fn index(&self, index: usize) -> &Self::Output {
567        assert!(index < self.len(), "Index out of bounds");
568        unsafe { &*self.as_ptr().add(index) }
569    }
570}
571
572impl<T, A> IndexMut<usize> for BSScrapArray<T, A>
573where
574    A: Allocator,
575{
576    #[inline]
577    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
578        assert!(index < self.len(), "Index out of bounds");
579        unsafe { &mut *self.as_mut_ptr().add(index) }
580    }
581}
582
583////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
584// Iterator
585
586/// Iterator returned by `BSTArray::drain()`
587pub struct BSTDrain<'a, T, A>
588where
589    A: Allocator,
590{
591    tail_start: usize, // = range.end
592    tail_len: usize,   // = original_len - range.end
593    iter: core::slice::Iter<'a, T>,
594    array: NonNull<BSScrapArray<T, A>>,
595}
596
597impl<T, A> Iterator for BSTDrain<'_, T, A>
598where
599    A: Allocator,
600{
601    type Item = T;
602
603    #[inline]
604    fn next(&mut self) -> Option<Self::Item> {
605        self.iter.next().map(|item| unsafe { ptr::read(item) })
606    }
607
608    #[inline]
609    fn size_hint(&self) -> (usize, Option<usize>) {
610        self.iter.size_hint()
611    }
612}
613
614impl<T, A> DoubleEndedIterator for BSTDrain<'_, T, A>
615where
616    A: Allocator,
617{
618    #[inline]
619    fn next_back(&mut self) -> Option<Self::Item> {
620        self.iter.next_back().map(|item| unsafe { ptr::read(item) })
621    }
622}
623
624impl<T, A> ExactSizeIterator for BSTDrain<'_, T, A>
625where
626    A: Allocator,
627{
628    #[inline]
629    fn len(&self) -> usize {
630        self.iter.len()
631    }
632}
633
634impl<T, A: Allocator> Drop for BSTDrain<'_, T, A> {
635    fn drop(&mut self) {
636        // Copyright (c) 2018 The Servo Project Developers
637        // SPDX-License-Identifier: Apache-2.0 OR MIT
638        // https://github.com/servo/rust-smallvec/blob/v2/src/lib.rs#L3
639
640        if core::mem::needs_drop::<T>() {
641            self.for_each(drop);
642        }
643
644        // Copy backward data not subject to drain to the drained start location
645        if self.tail_len > 0 {
646            unsafe {
647                let array = self.array.as_mut();
648
649                let start = array.len();
650                let tail = self.tail_start;
651                if tail != start {
652                    let ptr = array.as_mut_ptr();
653                    let src = ptr.add(tail);
654                    let dst = ptr.add(start);
655                    ptr::copy(src, dst, self.tail_len);
656                }
657                array.__base1.size = (start + self.tail_len) as u32;
658            }
659        }
660    }
661}
662
663////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
664
665pub struct BSTArrayIterator<'a, T, A>
666where
667    A: Allocator,
668{
669    array: &'a BSScrapArray<T, A>,
670    index: usize,
671}
672
673impl<'a, T, A> Iterator for BSTArrayIterator<'a, T, A>
674where
675    A: Allocator,
676{
677    type Item = &'a T;
678
679    #[inline]
680    fn next(&mut self) -> Option<Self::Item> {
681        if self.index < self.array.len() {
682            let item = unsafe { &*self.array.as_ptr().add(self.index) };
683            self.index += 1;
684            Some(item)
685        } else {
686            None
687        }
688    }
689}
690
691pub struct BSTArrayIntoIterator<T, A>
692where
693    A: Allocator,
694{
695    array: BSScrapArray<T, A>,
696    index: usize,
697}
698
699impl<T, A> Iterator for BSTArrayIntoIterator<T, A>
700where
701    A: Allocator,
702{
703    type Item = T;
704
705    #[inline]
706    fn next(&mut self) -> Option<Self::Item> {
707        if self.index < self.array.len() {
708            let item = unsafe { ptr::read(self.array.as_ptr().add(self.index)) };
709            self.index += 1;
710            Some(item)
711        } else {
712            None
713        }
714    }
715}
716
717impl<T, A> IntoIterator for BSScrapArray<T, A>
718where
719    A: Allocator,
720{
721    type Item = T;
722    type IntoIter = BSTArrayIntoIterator<T, A>;
723
724    #[inline]
725    fn into_iter(self) -> Self::IntoIter {
726        BSTArrayIntoIterator { array: self, index: 0 }
727    }
728}
729
730impl<'a, T, A> IntoIterator for &'a BSScrapArray<T, A>
731where
732    A: Allocator,
733{
734    type Item = &'a T;
735    type IntoIter = BSTArrayIterator<'a, T, A>;
736
737    #[inline]
738    fn into_iter(self) -> Self::IntoIter {
739        BSTArrayIterator { array: self, index: 0 }
740    }
741}
742
743pub struct BSTArrayIterMut<'a, T, A>
744where
745    A: Allocator,
746{
747    array: &'a mut BSScrapArray<T, A>,
748    index: usize,
749}
750
751impl<'a, T, A> Iterator for BSTArrayIterMut<'a, T, A>
752where
753    A: Allocator,
754{
755    type Item = &'a mut T;
756
757    #[inline]
758    fn next(&mut self) -> Option<Self::Item> {
759        if self.index < self.array.len() {
760            unsafe {
761                let ptr = self.array.as_mut_ptr().add(self.index);
762                self.index += 1;
763                Some(&mut *ptr)
764            }
765        } else {
766            None
767        }
768    }
769
770    #[inline]
771    fn size_hint(&self) -> (usize, Option<usize>) {
772        let len = self.array.len();
773        (len, Some(len))
774    }
775}
776
777impl<'a, T, A> IntoIterator for &'a mut BSScrapArray<T, A>
778where
779    A: Allocator,
780{
781    type Item = &'a mut T;
782    type IntoIter = BSTArrayIterMut<'a, T, A>;
783
784    #[inline]
785    fn into_iter(self) -> Self::IntoIter {
786        BSTArrayIterMut { array: self, index: 0 }
787    }
788}
789
790impl<T, A> Extend<T> for BSScrapArray<T, A>
791where
792    A: Allocator,
793{
794    #[inline]
795    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
796        for elem in iter {
797            self.push(elem);
798        }
799    }
800}
801
802////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
803// Standard derive
804
805impl<T, A> core::fmt::Debug for BSScrapArray<T, A>
806where
807    T: core::fmt::Debug,
808    A: Allocator,
809{
810    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
811        f.debug_list().entries(self.as_slice()).finish()
812    }
813}
814
815impl<T, A> Default for BSScrapArray<T, A>
816where
817    A: Allocator,
818{
819    #[inline]
820    fn default() -> Self {
821        Self::new()
822    }
823}
824
825impl<T, A> Clone for BSScrapArray<T, A>
826where
827    A: Allocator + Clone,
828{
829    #[inline]
830    fn clone(&self) -> Self {
831        if self.__base.capacity() == 0 {
832            return Self::new();
833        }
834
835        Self {
836            __base: self.__base.clone(),
837            __base1: BSTArrayBase { size: self.__base1.size },
838            _marker: PhantomData,
839        }
840    }
841}
842
843impl<T, A> PartialEq for BSScrapArray<T, A>
844where
845    T: PartialEq,
846    A: Allocator,
847{
848    #[inline]
849    fn eq(&self, other: &Self) -> bool {
850        self.as_slice() == other.as_slice()
851    }
852}
853impl<T, A> PartialEq<Vec<T>> for BSScrapArray<T, A>
854where
855    T: PartialEq,
856    A: Allocator,
857{
858    #[inline]
859    fn eq(&self, other: &Vec<T>) -> bool {
860        self.as_slice() == *other
861    }
862}
863
864impl<T, A> PartialEq<&[T]> for BSScrapArray<T, A>
865where
866    T: PartialEq,
867    A: Allocator,
868{
869    #[inline]
870    fn eq(&self, other: &&[T]) -> bool {
871        self.as_slice() == *other
872    }
873}
874
875impl<T, A> Eq for BSScrapArray<T, A>
876where
877    T: Eq,
878    A: Allocator,
879{
880}
881
882impl<T, A> PartialOrd for BSScrapArray<T, A>
883where
884    T: PartialOrd,
885    A: Allocator,
886{
887    #[inline]
888    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
889        self.as_slice().partial_cmp(other.as_slice())
890    }
891}
892
893impl<T, A> Ord for BSScrapArray<T, A>
894where
895    T: Ord,
896    A: Allocator,
897{
898    #[inline]
899    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
900        self.as_slice().cmp(other.as_slice())
901    }
902}
903
904impl<T, A> core::hash::Hash for BSScrapArray<T, A>
905where
906    T: core::hash::Hash,
907    A: Allocator,
908{
909    #[inline]
910    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
911        self.as_slice().hash(state);
912    }
913}